什么是相互认证
相互身份验证也称为双向身份验证。它是一个过程,在这个过程中,客户机和服务器都通过证书颁发机构彼此验证身份。CodeProject.com对互认证有一个很好的定义:
相互SSL认证或基于证书的相互认证是指双方通过验证提供的数字证书来相互认证,以便双方确保其他人的身份。
在项目中我们经常会用到https双向认证,通常我们在nginx 配置https 双向证书:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Nginx HTTPS双向认证配置参考
server {
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1;
server_name www.example.com; #域名
ssl_certificate www.example.com.crt; #第三方或自签发的证书
ssl_certificate_key www.example.com.key; #和证书配对的私钥
ssl_verify_client on; #验证请求来源
ssl_client_certificate ca.crt; #CA根证书
ssl_verify_depth 2;
ssl_crl ssl/dr-crl.chain.pem; # 客户端证书链
location / {
root html;
index index.html index.htm;
}
}
同样,在k8s中我们可以借助ingress实现
部署 Ingress Controller
这里使用kubespray部署的集群,故使用脚本默认的nginx-ingress
设置相互身份验证
要设置相互身份验证,您需要执行几个步骤。
创建证书
对于此示例,我们将创建自签名证书(仅用于测试目的,而不是在生产中完成)。 作为一个简单的介绍,这里有几个术语,有用的知道:
CommonName(CN):标识与证书关联的主机名或所有者。
证书颁发机构(CA):颁发证书的受信任第三方。 通常你会从一个受信任的来源获得这个,但是对于这个例子我们只会创建一个。 CN通常是发行人的名称。
服务器证书:用于标识服务器的证书。 这里的CN是服务器的主机名。 仅当服务器证书安装在主机名与CN匹配的服务器上时,服务器证书才有效。
客户端证书:用于标识客户端/用户的证书。 这里的CN通常是客户端/用户的名称。
1 | # 生成根秘钥及证书 |
Github证书参考链接:
Creating the CA Authentication secret
Client Certificate Authentication
创建 k8s secret
我们需要将上面生成的证书存储在Kubernetes Secret中,以便在我们的Ingress-NGINX控制器中使用它们。
在此示例中,为简单起见,这个 secret 将包含 服务器证书 和 CA证书 。Ingress Controller将会自动匹配使用哪些证书以及在何处使用它们。它们也可以分成单独的secret,可以参考这里
1 | $ kubectl create secret generic my-certs --from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt |
部署测试服务
部署一个nginx
1 |
|
添加双向证书ingress 服务
1 | apiVersion: extensions/v1beta1 |
- TLS已启用,它会使用my-certs secret中提供的tls.key和tls.crt。
- nginx.ingress.kubernetes.io/auth-tls-secret批注使用my-certs secret中的ca.crt。
测试
浏览器访问 https://meow.com 并导入我们生成的p12证书
注意事项
kubespray 默认部署的ingress-nginx ssl-protocols 只开启了SSLv2 协议。 我们需要添加TLSv1 TLSv1.1 TLSv1.2完整的 ssl 协议
这里 https://kubernetes.github.io/ingress-nginx/user-guide/tls/
1 | cat cm-ingress-nginx.yml |
HTTPS 证书添加1
kubectl create secret generic test.com-secret --from-file=tls.crt=test.com.pem --from-file=tls.key=test.com.key -n ftc-demo